﻿module Sustainalytics.Screening {
    import Common = Sustainalytics.Common;

    export class FilterCriteriaService implements IFilterCriteriaService {

        private urlBase: string;

        constructor(
            private $q: ng.IQService,
            private $http: ng.IHttpService,
            private $location: ng.ILocationService,
            private notificationFactory: Common.INotificationFactory,
            private staticObjects: Common.IStaticObjects,
            private $rootScope: ng.IScope) {
        }

        // show error message for a given error code
        private showError(err) {
            var ctx = this;
            if (err && err['errorCode'])
                ctx.notificationFactory.error('', ctx.staticObjects.getErrorMesageByStatusCode(err['errorCode'], err['errorCode']));
        }

        private showMessage(msg) {
            var ctx = this;
            ctx.notificationFactory.success(msg);
        }

        private filterCriteriaUrl(filterid: string, id?: string): string {
            return this.$location.protocol() + "://" + this.$location.host() + ":" + this.$location.port() + this.staticObjects.screeningToolServBaseUrl
                + "/filters/" + filterid + "/criteria/" + ((id) ? id : "");
        }

        //#region AddCriteria to filter
        public addCriteriaTypeOne(filterId, criteriaLevel2Id, criteriaTemplateId, minValue, maxValue, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: this.filterCriteriaUrl(filterId, null) + "?criteriaType=1&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { id: criteriaTemplateId, minValue: minValue, maxValue: maxValue }
            });
        }

        public addCriteriaTypeTwo(filterId, filterGroupId, criteriaLevel2Id, typeTwoIsScreenableCriteriaItems, typeTwoIsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: ctx.filterCriteriaUrl(filterId, null) + "?criteriaType=2&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { isScreenableCriteriaItems: typeTwoIsScreenableCriteriaItems, isNotScreenableCriteriaItems: typeTwoIsNotScreenableCriteriaItems }
            });
        }

        public addCriteriaTypeThree(filterId, criteriaLevel2Id, criteriaTemplateId, typeThreeIsScreenableItems, typeThreeIsNotScreenableItems, filterGroupId, isUpdate) {
            var ctx = this;            
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: this.filterCriteriaUrl(filterId, null) + "?criteriaType=3&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { id: criteriaTemplateId, isScreenableCriteriaItems: typeThreeIsScreenableItems, isNotScreenableCriteriaItems: typeThreeIsNotScreenableItems}
            });
        }

        public addCriteriaTypeFour(filterId, criteriaLevel2Id, filterGroupId, criteriaTypeFour, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: this.filterCriteriaUrl(filterId, null) + "?criteriaType=4&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: criteriaTypeFour 
            })
        }

        public addCriteriaTypeFive(filterId, filterGroupId, criteriaLevel2Id, typeFiveIsScreenableCriteriaItems, typeFiveIsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: ctx.filterCriteriaUrl(filterId, null) + "?criteriaType=5&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { isScreenableCriteriaItems: typeFiveIsScreenableCriteriaItems, isNotScreenableCriteriaItems: typeFiveIsNotScreenableCriteriaItems }
            });
        }

        public addCriteriaTypeSix(filterId, filterGroupId, criteriaLevel2Id, criteriaTemplateId, minValue, maxValue, type6IsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: this.filterCriteriaUrl(filterId, null) + "?criteriaType=6&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { id: criteriaTemplateId, minValue: minValue, maxValue: maxValue, isNotScreenableCriteriaItems: type6IsNotScreenableCriteriaItems }
            });
        }

        public addCriteriaTypeSeven(filterId, filterGroupId, criteriaLevel2Id, typeSevenIsScreenableCriteriaItems, typeSevenIsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: this.filterCriteriaUrl(filterId, null) + "?criteriaType=7&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { isScreenableCriteriaItems: typeSevenIsScreenableCriteriaItems, isNotScreenableCriteriaItems: typeSevenIsNotScreenableCriteriaItems }
            });
        }

        public addCriteriaTypeEight(filterId, filterGroupId, criteriaLevel2Id, typeEightIsScreenableCriteriaItems, typeEightIsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: ctx.filterCriteriaUrl(filterId, null) + "?criteriaType=8&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { isScreenableCriteriaItems: typeEightIsScreenableCriteriaItems, isNotScreenableCriteriaItems: typeEightIsNotScreenableCriteriaItems }
            });
        }

        public addCriteriaTypeNine(filterId, filterGroupId, criteriaLevel2Id, typeNineIsScreenableCriteriaItems, typeNineIsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: ctx.filterCriteriaUrl(filterId, null) + "?criteriaType=9&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { isScreenableCriteriaItems: typeNineIsScreenableCriteriaItems, isNotScreenableCriteriaItems: typeNineIsNotScreenableCriteriaItems }
            });
        }

        public addCriteriaTypeTen(filterId, filterGroupId, criteriaLevel2Id, typeTenIsScreenableCriteriaItems, typeTenIsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: ctx.filterCriteriaUrl(filterId, null) + "?criteriaType=9&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { isScreenableCriteriaItems: typeTenIsScreenableCriteriaItems, isNotScreenableCriteriaItems: typeTenIsNotScreenableCriteriaItems }
            });
        }

        public addCriteriaType16(filterId, filterGroupId, criteriaLevel2Id, criteriaTemplateId, minValue, maxValue, type16IsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: ctx.filterCriteriaUrl(filterId, null) + "?criteriaType=16&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { id: criteriaTemplateId, minValue: minValue, maxValue: maxValue, isNotScreenableCriteriaItems: type16IsNotScreenableCriteriaItems }
            });
        }

        public addCriteriaType17(filterId, filterGroupId, criteriaLevel2Id, type17IsScreenableCriteriaItems, type17IsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: ctx.filterCriteriaUrl(filterId, null) + "?criteriaType=17&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { isScreenableCriteriaItems: type17IsScreenableCriteriaItems, isNotScreenableCriteriaItems: type17IsNotScreenableCriteriaItems }
            });
        }

        public addCriteriaType25(filterId, filterGroupId, criteriaLevel2Id, type25IsScreenableCriteriaItems, type25IsNotScreenableCriteriaItems, isUpdate) {
            var ctx = this;
            var filterGroupParam = isUpdate ? "&filterGroupId=" + filterGroupId : "";
            return this.$http({
                method: isUpdate ? "PUT" : "POST",
                url: ctx.filterCriteriaUrl(filterId, null) + "?criteriaType=25&criteriaLevel2Id=" + criteriaLevel2Id + filterGroupParam,
                data: { isScreenableCriteriaItems: type25IsScreenableCriteriaItems, isNotScreenableCriteriaItems: type25IsNotScreenableCriteriaItems }
            });
        }

        //#endregion

        public addFilterCriteriaToFilter(filterId, listSelectedFilterCriteria) {
            var ctx = this;
            return this.$http({
                method: "POST",
                url: ctx.filterCriteriaUrl(filterId, null),
                data: listSelectedFilterCriteria 
            });
        }

        //#region GetCriteria for filter
        public getSelectedCriteriaByFilterCriteriaId(filterId: string, filterCriteriaId: string)
        {
            var ctx = this;
            var def = this.$q.defer();

            var url = ctx.filterCriteriaUrl(filterId, filterCriteriaId);
            var promise = this.$http.get(url);

            promise
                .success(
                function (data) {
                    def.resolve(data);
                })
                .error(
                function (err) {
                    ctx.showError(err);
                    def.reject();
                })
            return def.promise;
        }

        public getFilterCriteriaByFilterId(filterId: string) {
            var ctx = this;
            var def = this.$q.defer();

            var url = ctx.filterCriteriaUrl(filterId, null);
            var promise = this.$http.get(url); 

            promise
                .success(
                function (data) {
                    def.resolve(data);
                })
                .error(
                function (err) {
                    ctx.showError(err);
                    def.reject();
                })
            return def.promise;
        }
        //#endregion

        //#region DeleteCriteria

        public deleteFilterCriteriaById(filterId: string, id: string) {
            var ctx = this;
            var def = this.$q.defer();

            var url = ctx.filterCriteriaUrl(filterId, id);

            var promise: ng.IHttpPromise<{}> = this.$http['delete'](url);

            promise.success(function (data) {
                def.resolve(data);
            })
                .error(function (err) {
                ctx.showError(err);
                def.reject();
            })
            return def.promise;
        }

        public deleteFilterCriteriaGroup(filterId: string, filterCriteriaId: string, filterGroupId: string) {
            var ctx = this;
            var def = this.$q.defer();

            var url = ctx.filterCriteriaUrl(filterId, null);

            var promise: ng.IHttpPromise < {} > = this.$http({
                method: "PATCH",
                url: this.filterCriteriaUrl(filterId, null) + '?filterCriteriaId=' + filterCriteriaId + "&filterGroupId=" + filterGroupId
            });

            promise.success(function (data) {
                def.resolve(data);
            })
                .error(function (err) {
                ctx.showError(err);
                def.reject();
            })
            return def.promise;
        }
        //#endregion
    }

    var mod = angular.module(screeningToolModuleName);

    mod.service('FilterCriteriaService',
        ['$q', '$http', '$location', 'notificationFactory', 'staticObjects', '$rootScope', FilterCriteriaService]);
}